/**
 * @file selection.h
 * @brief Genetic functions for selecting modules for reproduction
 * @author Scott Moyers
 * @date 2009
 */

#ifndef MY_SELECTION_H
#define MY_SELECTION_H

#include "module.h"

/** Creates a type for function pointers to selection functions */
typedef void (*SelectionFunc) (dsfmt_t *dsfmt, struct Module *m[], unsigned int n, unsigned int sel);

/** number of selection functions, update as necessary */
#define SEL_FUNCS (4)

/**
 * takes an array of modules and sorts them into fitness order (fittest first)
 * you can then pick the first n modules in the array as the fittest
 * @param dsfmt unused
 * @param m array of possibly un-sorted modules
 * @param n number of modules in the module array
 * @param sel unused
 */
void fittest_selection(dsfmt_t *dsfmt, struct Module *m[], unsigned int n, unsigned int sel);

/**
 * roulette wheel selection. selects the circuits with a probability
 * proportional to its the modules fitness.
 * @param dsfmt random number generator
 * @param m array of possibly un-sorted modules
 * @param n number of modules in the module array
 * @param sel number of modules to select
 */
void roulette_wheel_selection(dsfmt_t *dsfmt, struct Module *m[], unsigned int n, unsigned int sel);

/**
 * tournament selection. randomly selects 2 circuits and keeps
 * the fittest until we have sel amount of circuits
 * @param dsfmt random number generator
 * @param m array of possibly un-sorted modules
 * @param n number of modules in the module array
 * @param sel number of modules to select
 */
void tournament_selection(dsfmt_t *dsfmt, struct Module *m[], unsigned int n, unsigned int sel);

/**
 * roulette tournament. selects 2 circuits using the roulette wheel approach
 * and adds the fittest to the selected circuits array.
 * @param dsfmt random number generator
 * @param m array of possibly un-sorted modules
 * @param n number of modules in the module array
 * @param sel number of modules to select
 */
void roulette_tournament_selection(dsfmt_t *dsfmt, struct Module *m[], unsigned int n, unsigned int sel);

/**
 * gets a function pointer to the function named "func"
 * @param func name of a selection function
 * @retval a function pointer
 * @retval NULL if the function doesn't exist
 */
SelectionFunc get_selection_func(const char *func);

#endif
